<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>kotlin-高阶函数 | litton ishir</title>
    <meta name="description" content="&quot;Someday&quot;sounds a lot like the thing people say when they actually mean &quot;Never&quot;. ">
    <link rel="icon" href="https://upload-images.jianshu.io/upload_images/1074123-dc819e68a5f3c3f7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
    
    <link rel="preload" href="/assets/css/0.styles.956f79c0.css" as="style"><link rel="preload" href="/assets/js/app.b387b3a3.js" as="script"><link rel="preload" href="/assets/js/7.905ce75a.js" as="script"><link rel="prefetch" href="/assets/js/10.89f8a53a.js"><link rel="prefetch" href="/assets/js/11.79be8c9b.js"><link rel="prefetch" href="/assets/js/2.abd3539a.js"><link rel="prefetch" href="/assets/js/3.6b6c4ca0.js"><link rel="prefetch" href="/assets/js/4.93ebd6e9.js"><link rel="prefetch" href="/assets/js/5.9a8427c2.js"><link rel="prefetch" href="/assets/js/6.0cda6858.js"><link rel="prefetch" href="/assets/js/8.12136322.js"><link rel="prefetch" href="/assets/js/9.f57e2ac2.js">
    <link rel="stylesheet" href="/assets/css/0.styles.956f79c0.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="container"><div id="head-c"><div class="row"><div class="offset-lg-2 col-lg-8 offset-md-1 col-md-10"><h1 id="blog-name"><a href="/" class="router-link-active">
                litton ishir
            </a></h1> <a href="https://weibo.com/littonishir" target="_blank" class="social"><i class="fa fa-fw fa-weibo"></i></a><a href="https://github.com/littonishir" target="_blank" class="social"><i class="fa fa-fw fa-github"></i></a><a href="https://space.bilibili.com/268398214/" target="_blank" class="social"><i class="fa fa-fw fa-terminal"></i></a><a href="https://www.instagram.com/littonishir/" target="_blank" class="social"><i class="fa fa-fw fa-instagram"></i></a></div></div></div> <div class="row"><div class="offset-lg-2 col-lg-8 offset-md-1 col-md-10"><div><article><p class="post-page-meta">Mar 28, 2017</p> <hr> <div class="content"><h1 id="kotlin-高阶函数"><a href="#kotlin-高阶函数" aria-hidden="true" class="header-anchor">#</a> kotlin-高阶函数</h1> <p>高阶函数:传入或者返回函数的函数</p> <p>函数引用的三种方式</p> <ol><li>包级函数作为高阶函数的参数的时候,直接按照参数返回值来判断是否合适.</li> <li>类的成员函数(带有Receiver的函数)作为高阶函数的参数的时候,需要使用实例来进行引用.</li> <li>扩展方法作为高阶函数的参数的时候,需要注意的是扩展方法有一个默认的参数就是实例本身</li></ol> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token keyword">fun</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">val</span> line <span class="token operator">=</span> <span class="token string">&quot;-------&quot;</span>
        <span class="token keyword">val</span> arrayInt <span class="token operator">=</span> <span class="token function">listOf</span><span class="token punctuation">(</span><span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">22</span><span class="token punctuation">,</span> <span class="token number">33</span><span class="token punctuation">,</span> <span class="token number">44</span><span class="token punctuation">,</span> <span class="token number">55</span><span class="token punctuation">)</span>
        <span class="token keyword">var</span> arrayStr <span class="token operator">=</span> <span class="token function">listOf</span><span class="token punctuation">(</span><span class="token string">&quot;杏本诗歌&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;守凪了子&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;西宫结弦&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;花畑佳子&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;冈部伦太郎&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">)</span>
        <span class="token comment">/**
         * 包级函数
         */</span>
        arrayInt<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token operator">::</span>println<span class="token punctuation">)</span>
        <span class="token function">println</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span>
        <span class="token comment">/**
         * 类的成员函数
         */</span>
        <span class="token keyword">val</span> pm <span class="token operator">=</span> <span class="token function">MyPrintln</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        arrayStr<span class="token punctuation">.</span><span class="token function">filter</span> <span class="token punctuation">{</span> it<span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span><span class="token string">&quot;子&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>pm<span class="token operator">::</span>println<span class="token punctuation">)</span>
        arrayStr<span class="token punctuation">.</span><span class="token function">filter</span> <span class="token punctuation">{</span> it<span class="token punctuation">.</span>length <span class="token operator">&gt;</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>pm<span class="token operator">::</span>println<span class="token punctuation">)</span>
        <span class="token function">println</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span>
         <span class="token comment">/**
         * 扩展方法
         */</span>
        arrayStr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>String<span class="token operator">::</span>isNotBlank<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token operator">::</span>println<span class="token punctuation">)</span>
        <span class="token function">println</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><p><a href="#package"><font size="2" color="#006666">包级函数</font></a></p> <h3 id="map"><a href="#map" aria-hidden="true" class="header-anchor">#</a> map</h3> <br> <ol><li>map:集合的映射</li> <li>map:集合的转换</li></ol> <div class="language-kt extra-class"><pre class="language-text"><code>        val arrayInt1 = arrayInt.map { it * 4 }
        val arrayDouble = arrayInt.map(Int::toDouble)
        println(arrayInt1)
        println(arrayDouble)
</code></pre></div><br> <h3 id="flatmap"><a href="#flatmap" aria-hidden="true" class="header-anchor">#</a> flatMap</h3> <br> <ol><li>flatMap:扁平化集合</li> <li>... RangeTo</li> <li>1..5:返回一个intRange(1,2,3,4,5)</li></ol> <div class="language-kt extra-class"><pre class="language-text"><code>        val list = arrayListOf(1..9, 233..255, 79..88)
        val flatMap = list.flatMap { it }
        flatMap.forEach(::println)
</code></pre></div><br> <h3 id="reduce"><a href="#reduce" aria-hidden="true" class="header-anchor">#</a> reduce</h3> <br> <ol><li>reduce通常用于求和</li></ol> <div class="language-kt extra-class"><pre class="language-text"><code>        println(flatMap.reduce(Int::plus))
        println(flatMap.reduce { acc, i -&gt; acc + i })
        //阶乘示例
        println(factorial(8))
</code></pre></div><ol start="2"><li>阶乘</li></ol> <div class="language-kt extra-class"><pre class="language-text"><code>    /**
     * 阶乘
     */
    private fun factorial(n: Int): Int {
        if (n == 0) return 1
        return (1..n).reduce { acc, i -&gt; acc * i }
    }
</code></pre></div><br> <h3 id="flod"><a href="#flod" aria-hidden="true" class="header-anchor">#</a> flod</h3> <br> <ol><li>fold:对集合进行自定义计算</li></ol> <div class="language-kt extra-class"><pre class="language-text"><code>        println((0..1).fold(8) { acc, i -&gt; acc + i })

        /**
         * joinToString:对集合进行转化和拼接
         */
        println((0..10).joinToString(&quot;,&quot;))
        val fold = (0..5).fold(StringBuilder()) { acc, i -&gt; acc.append(i).append(&quot;,&quot;) }
        println(fold)

</code></pre></div><ol start="2"><li>字符串拼接</li></ol> <div class="language-kt extra-class"><pre class="language-text"><code>        println((0..10).joinToString(&quot;,&quot;))
</code></pre></div><br> <h3 id="filter"><a href="#filter" aria-hidden="true" class="header-anchor">#</a> filter</h3> <br> <ol><li>filter用于过滤,传入表达式的值为true时保留:</li></ol> <div class="language-kt extra-class"><pre class="language-text"><code>     	val pm = MyPrintln()
        arrayStr.filter { it.contains(&quot;子&quot;) }.forEach(pm::println)
        arrayStr.filter { it.length &gt; 4 }.forEach(pm::println)
</code></pre></div><br> <h3 id="takewhile"><a href="#takewhile" aria-hidden="true" class="header-anchor">#</a> takeWhile</h3> <br> <ol><li>takeWhile通常用于带有条件的循环遍历,直到第一个不满足条件元素出现循环结束.</li></ol> <div class="language-kt extra-class"><pre class="language-text"><code>		 //直到第一个不小于44的元素出现,循环结束.
		 //最后输出元素应为(11,22,33)
        val arrayInt = listOf(11, 22, 33, 44, 55)
        arrayInt.takeWhile { it&lt;44 }.forEach(::println)
</code></pre></div><br> <h3 id="补充说明"><a href="#补充说明" aria-hidden="true" class="header-anchor">#</a> 补充说明</h3> <br> <ul><li>包级函数:在包内直接声明函数的方式叫作包级函数</li></ul> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token keyword">package</span> com<span class="token punctuation">.</span>litton<span class="token punctuation">.</span>ishir

<span class="token keyword">inline</span> <span class="token keyword">fun</span> <span class="token function">print</span><span class="token punctuation">(</span>message<span class="token operator">:</span> Int<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="data-class"><a href="#data-class" aria-hidden="true" class="header-anchor">#</a> data class</h3> <br> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>    <span class="token keyword">data</span> <span class="token keyword">class</span> <span class="token function">singer</span><span class="token punctuation">(</span><span class="token keyword">var</span> name<span class="token operator">:</span> String<span class="token punctuation">,</span> <span class="token keyword">var</span> song<span class="token operator">:</span> String<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">fun</span> <span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;<span class="token interpolation variable">$name</span>,演唱新单曲<span class="token interpolation variable">$song</span>&quot;</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="let"><a href="#let" aria-hidden="true" class="header-anchor">#</a> let</h3> <br> <ul><li>let: it表示引用对象,可调用其成员(属性以及方法),it不可省略.</li> <li>返回值: 返回值为函数块的最后一行,为空就返回一个Unit类型的默认值.</li></ul> <p>使用:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>KaryNg<span class="token punctuation">.</span><span class="token function">let</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>	<span class="token comment">//在函数体内使用it替代引用对象去访问其公有的属性和方法</span>
KaryNg<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">let</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>	<span class="token comment">//另一种用途:?判断对象是否为空,不为空才会执行let函数体</span>
</code></pre></div><p>例子:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>    <span class="token keyword">fun</span> <span class="token function">main</span><span class="token punctuation">(</span>args<span class="token operator">:</span> Array<span class="token operator">&lt;</span>String<span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">val</span> KaryNg <span class="token operator">=</span> <span class="token function">singer</span><span class="token punctuation">(</span><span class="token string">&quot;吴雨霏&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;我本人&quot;</span><span class="token punctuation">)</span>
        <span class="token keyword">val</span> kary<span class="token operator">:</span> Any <span class="token operator">=</span> KaryNg<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">let</span> <span class="token punctuation">{</span>
            it<span class="token punctuation">.</span>song
            it<span class="token punctuation">.</span>name<span class="token punctuation">.</span>length
        <span class="token punctuation">}</span>
        <span class="token function">println</span><span class="token punctuation">(</span>kary<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><p>输出:</p> <p>singer(name=吴雨霏, song= &lt;&lt;我本人&gt;&gt;)<br>
3</p> <p>适用场景:<br>
使用let函数处理需要针对一个可null的对象统一做判空处理.<br>
官方源码:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token comment">/**
 * Calls the specified function [block] with `this` value as its argument and returns its result.
 */</span>
<span class="token label symbol">@kotlin</span><span class="token punctuation">.</span>internal<span class="token punctuation">.</span>InlineOnly
<span class="token keyword">public</span> <span class="token keyword">inline</span> <span class="token keyword">fun</span> <span class="token operator">&lt;</span>T<span class="token punctuation">,</span> R<span class="token operator">&gt;</span> T<span class="token punctuation">.</span><span class="token function">let</span><span class="token punctuation">(</span>block<span class="token operator">:</span> <span class="token punctuation">(</span>T<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> R<span class="token punctuation">)</span><span class="token operator">:</span> R <span class="token punctuation">{</span>
    contract <span class="token punctuation">{</span>
        <span class="token function">callsInPlace</span><span class="token punctuation">(</span>block<span class="token punctuation">,</span> InvocationKind<span class="token punctuation">.</span>EXACTLY_ONCE<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token function">block</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="also"><a href="#also" aria-hidden="true" class="header-anchor">#</a> also</h3> <br> <ul><li>also: it表示引用对象,可调用其成员(属性以及方法),it不可省略.<br></li> <li>返回值: 返回值为函数块的最后一行,为空就返回一个Unit类型的默认值.</li></ul> <p>使用:</p> <p>also函数结构实际上和let很像唯一的区别就是返回值不一样,let以闭包的形式返回,返回函数体内最后一行的值,如果最后一行为空就返回一个Unit类型的默认值.而also函数则返回传入对象本身.</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>        KaryNg<span class="token punctuation">.</span><span class="token function">run</span> <span class="token punctuation">{</span>  <span class="token punctuation">}</span>
</code></pre></div><p>例子:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>    <span class="token keyword">fun</span> <span class="token function">main</span><span class="token punctuation">(</span>args<span class="token operator">:</span> Array<span class="token operator">&lt;</span>String<span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">val</span> KaryNg <span class="token operator">=</span> <span class="token function">singer</span><span class="token punctuation">(</span><span class="token string">&quot;吴雨霏&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;我本人&quot;</span><span class="token punctuation">)</span>
        <span class="token keyword">val</span> kary<span class="token operator">:</span> Any <span class="token operator">=</span> KaryNg<span class="token operator">?</span><span class="token punctuation">.</span> also <span class="token punctuation">{</span>
            it<span class="token punctuation">.</span>song
            it<span class="token punctuation">.</span>name<span class="token punctuation">.</span>length
        <span class="token punctuation">}</span>
        <span class="token function">println</span><span class="token punctuation">(</span>kary<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><p>输出:</p> <p>吴雨霏,演唱新单曲 &lt;&lt;我本人&gt;&gt;<br>
singer(name=吴雨霏, song= &lt;&lt;我本人&gt;&gt;)</p> <p>适用场景:一般可用于多个扩展函数链式调用<br>
官方源码:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token comment">/**
 * Calls the specified function [block] with `this` value as its argument and returns `this` value.
 */</span>
<span class="token label symbol">@kotlin</span><span class="token punctuation">.</span>internal<span class="token punctuation">.</span>InlineOnly
<span class="token annotation builtin">@SinceKotlin</span><span class="token punctuation">(</span><span class="token string">&quot;1.1&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">inline</span> <span class="token keyword">fun</span> <span class="token operator">&lt;</span>T<span class="token operator">&gt;</span> T<span class="token punctuation">.</span><span class="token function">also</span><span class="token punctuation">(</span>block<span class="token operator">:</span> <span class="token punctuation">(</span>T<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> Unit<span class="token punctuation">)</span><span class="token operator">:</span> T <span class="token punctuation">{</span>
    contract <span class="token punctuation">{</span>
        <span class="token function">callsInPlace</span><span class="token punctuation">(</span>block<span class="token punctuation">,</span> InvocationKind<span class="token punctuation">.</span>EXACTLY_ONCE<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token function">block</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span>
<span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="with"><a href="#with" aria-hidden="true" class="header-anchor">#</a> with</h3> <br> <ul><li>with: 在函数块内通过 this 指代对象,调用成员(属性以及方法),this可省略.<br></li> <li>返回值: 返回值为函数块的最后一行,为空就返回一个Unit类型的默认值.</li></ul> <p>使用:</p> <blockquote><p>with函数和前面的函数使用方式略有不同,它不是以扩展函数.它将对象作为函数的参数</p></blockquote> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>        <span class="token function">with</span><span class="token punctuation">(</span>KaryNg<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span>
</code></pre></div><p>例子:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>    <span class="token keyword">fun</span> <span class="token function">main</span><span class="token punctuation">(</span>args<span class="token operator">:</span> Array<span class="token operator">&lt;</span>String<span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">val</span> KaryNg <span class="token operator">=</span> <span class="token function">singer</span><span class="token punctuation">(</span><span class="token string">&quot;吴雨霏&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;我本人&quot;</span><span class="token punctuation">)</span>
 		<span class="token keyword">val</span> sing<span class="token operator">=</span><span class="token function">with</span><span class="token punctuation">(</span>KaryNg<span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token function">println</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
            <span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            name
        <span class="token punctuation">}</span>
            <span class="token function">println</span><span class="token punctuation">(</span>sing<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><p>输出:</p> <blockquote><p>singer(name=吴雨霏, song= &lt;&lt;我本人&gt;&gt;)<br>
吴雨霏,演唱新单曲 &lt;&lt;我本人&gt;&gt; <br>
吴雨霏</p></blockquote> <p>适用场景:</p> <blockquote><p>适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类方法即可,经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性映射到UI上</p></blockquote> <p>官方源码:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token comment">/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 */</span>
<span class="token label symbol">@kotlin</span><span class="token punctuation">.</span>internal<span class="token punctuation">.</span>InlineOnly
<span class="token keyword">public</span> <span class="token keyword">inline</span> <span class="token keyword">fun</span> <span class="token operator">&lt;</span>T<span class="token punctuation">,</span> R<span class="token operator">&gt;</span> <span class="token function">with</span><span class="token punctuation">(</span>receiver<span class="token operator">:</span> T<span class="token punctuation">,</span> block<span class="token operator">:</span> T<span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> R<span class="token punctuation">)</span><span class="token operator">:</span> R <span class="token punctuation">{</span>
    contract <span class="token punctuation">{</span>
        <span class="token function">callsInPlace</span><span class="token punctuation">(</span>block<span class="token punctuation">,</span> InvocationKind<span class="token punctuation">.</span>EXACTLY_ONCE<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> receiver<span class="token punctuation">.</span><span class="token function">block</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="run"><a href="#run" aria-hidden="true" class="header-anchor">#</a> run</h3> <br> <ul><li>run: 在函数块内通过 this 指代对象,调用成员(属性以及方法),this可省略.<br></li> <li>返回值: 返回值为函数块的最后一行,为空就返回一个Unit类型的默认值.</li></ul> <p>使用:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>        KaryNg<span class="token punctuation">.</span><span class="token function">run</span> <span class="token punctuation">{</span>  <span class="token punctuation">}</span>
</code></pre></div><p>例子:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>    <span class="token keyword">fun</span> <span class="token function">main</span><span class="token punctuation">(</span>args<span class="token operator">:</span> Array<span class="token operator">&lt;</span>String<span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">val</span> KaryNg <span class="token operator">=</span> <span class="token function">singer</span><span class="token punctuation">(</span><span class="token string">&quot;吴雨霏&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;我本人&quot;</span><span class="token punctuation">)</span>
 		<span class="token keyword">val</span> kary<span class="token operator">:</span> Any <span class="token operator">=</span> KaryNg<span class="token punctuation">.</span><span class="token function">run</span> <span class="token punctuation">{</span>
            	<span class="token function">println</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
            	<span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            	name<span class="token punctuation">.</span>length
       	 	<span class="token punctuation">}</span>
        	<span class="token function">println</span><span class="token punctuation">(</span>kary<span class="token punctuation">)</span> 
     <span class="token punctuation">}</span>
</code></pre></div><p>输出:</p> <blockquote><p>singer(name=吴雨霏, song= &lt;&lt;我本人&gt;&gt;)<br>
吴雨霏,演唱新单曲 &lt;&lt;我本人&gt;&gt; <br>
3</p></blockquote> <p>适用场景:</p> <blockquote><p>适用于let,with函数任何场景.run函数是let,with两个函数结合体,准确来说它弥补了let函数在函数体内必须使用it参数替代对象,在run函数中可以像with函数一样可以省略,直接访问实例的公有属性和方法,另一方面它弥补了with函数传入对象判空问题,在run函数中可以像let函数一样做判空处理</p></blockquote> <p>官方源码:</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token comment">/**
 * Calls the specified function [block] with `this` value as its receiver and returns its result.
 */</span>
<span class="token label symbol">@kotlin</span><span class="token punctuation">.</span>internal<span class="token punctuation">.</span>InlineOnly
<span class="token keyword">public</span> <span class="token keyword">inline</span> <span class="token keyword">fun</span> <span class="token operator">&lt;</span>T<span class="token punctuation">,</span> R<span class="token operator">&gt;</span> T<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>block<span class="token operator">:</span> T<span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> R<span class="token punctuation">)</span><span class="token operator">:</span> R <span class="token punctuation">{</span>
    contract <span class="token punctuation">{</span>
        <span class="token function">callsInPlace</span><span class="token punctuation">(</span>block<span class="token punctuation">,</span> InvocationKind<span class="token punctuation">.</span>EXACTLY_ONCE<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token function">block</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="apply"><a href="#apply" aria-hidden="true" class="header-anchor">#</a> apply</h3> <br> <ul><li>with: 在函数块内通过 this 指代对象,调用成员(属性以及方法),this可省略.<br></li> <li>返回值: 返回值为函数块的最后一行,为空就返回一个Unit类型的默认值.</li></ul> <p>使用:</p> <blockquote><p>从结构上来看apply函数和run函数很像,唯一不同就是它们返回值不一样,run函数以闭包形式返回最后一行代码的值,而apply函数的返回传入对象本身</p></blockquote> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>        KaryNg<span class="token punctuation">.</span><span class="token function">apply</span> <span class="token punctuation">{</span>  <span class="token punctuation">}</span>
</code></pre></div><p>例子</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>    <span class="token keyword">fun</span> <span class="token function">main</span><span class="token punctuation">(</span>args<span class="token operator">:</span> Array<span class="token operator">&lt;</span>String<span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">val</span> KaryNg <span class="token operator">=</span> <span class="token function">singer</span><span class="token punctuation">(</span><span class="token string">&quot;吴雨霏&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;我本人&quot;</span><span class="token punctuation">)</span>
        <span class="token keyword">val</span> kary<span class="token operator">:</span> Any <span class="token operator">=</span> KaryNg<span class="token punctuation">.</span><span class="token function">apply</span> <span class="token punctuation">{</span>
            song
            <span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
        <span class="token function">println</span><span class="token punctuation">(</span>kary<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><p>输出</p> <blockquote><p>吴雨霏,演唱新单曲我本人<br>
singer(name=吴雨霏, song=我本人)</p></blockquote> <p>适用场景:</p> <blockquote><p>apply一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值.或者动态inflate出一个XML的View的时候需要给View绑定数据也会用到,这种情景非常常见.特别是在我们开发中会有一些数据model向View model转化实例化的过程中需要用到.</p></blockquote> <p>官方源码</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token comment">/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 */</span>
<span class="token label symbol">@kotlin</span><span class="token punctuation">.</span>internal<span class="token punctuation">.</span>InlineOnly
<span class="token keyword">public</span> <span class="token keyword">inline</span> <span class="token keyword">fun</span> <span class="token operator">&lt;</span>T<span class="token operator">&gt;</span> T<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>block<span class="token operator">:</span> T<span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> Unit<span class="token punctuation">)</span><span class="token operator">:</span> T <span class="token punctuation">{</span>
    contract <span class="token punctuation">{</span>
        <span class="token function">callsInPlace</span><span class="token punctuation">(</span>block<span class="token punctuation">,</span> InvocationKind<span class="token punctuation">.</span>EXACTLY_ONCE<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token function">block</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span>
<span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="use"><a href="#use" aria-hidden="true" class="header-anchor">#</a> use</h3> <br>
未完结
<ul><li>use: 在函数块内通过 it 指代对象,调用成员(属性以及方法),it不可省略.<br></li> <li>返回值: 返回值为函数块的最后一行,为空就返回一个Unit类型的默认值.</li></ul> <p>例子</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code> <span class="token keyword">val</span> read <span class="token operator">=</span> <span class="token function">BufferedReader</span><span class="token punctuation">(</span><span class="token function">FileReader</span><span class="token punctuation">(</span><span class="token string">&quot;build.gradle&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">use</span> <span class="token punctuation">{</span>
            <span class="token keyword">val</span> readText <span class="token operator">=</span> it<span class="token punctuation">.</span><span class="token function">readLine</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            readText
        <span class="token punctuation">}</span>
        <span class="token function">println</span><span class="token punctuation">(</span>read<span class="token punctuation">)</span>
</code></pre></div><p>输出 apply plugin: 'com.android.application'</p> <p>适用场景:use自己关流.</p> <p>官方源码</p> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token comment">/**
 * Executes the given [block] function on this resource and then closes it down correctly whether an exception
 * is thrown or not.
 *
 * @param block a function to process this [Closeable] resource.
 * @return the result of [block] function invoked on this resource.
 */</span>
<span class="token annotation builtin">@InlineOnly</span>
<span class="token annotation builtin">@RequireKotlin</span><span class="token punctuation">(</span><span class="token string">&quot;1.2&quot;</span><span class="token punctuation">,</span> versionKind <span class="token operator">=</span> RequireKotlinVersionKind<span class="token punctuation">.</span>COMPILER_VERSION<span class="token punctuation">,</span> message <span class="token operator">=</span> <span class="token string">&quot;Requires newer compiler version to be inlined correctly.&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">inline</span> <span class="token keyword">fun</span> <span class="token operator">&lt;</span>T <span class="token operator">:</span> Closeable<span class="token operator">?</span><span class="token punctuation">,</span> R<span class="token operator">&gt;</span> T<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>block<span class="token operator">:</span> <span class="token punctuation">(</span>T<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> R<span class="token punctuation">)</span><span class="token operator">:</span> R <span class="token punctuation">{</span>
    <span class="token keyword">var</span> exception<span class="token operator">:</span> Throwable<span class="token operator">?</span> <span class="token operator">=</span> <span class="token keyword">null</span>
    <span class="token keyword">try</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token function">block</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token operator">:</span> Throwable<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        exception <span class="token operator">=</span> e
        <span class="token keyword">throw</span> e
    <span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span>
        <span class="token keyword">when</span> <span class="token punctuation">{</span>
            <span class="token function">apiVersionIsAtLeast</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">closeFinally</span><span class="token punctuation">(</span>exception<span class="token punctuation">)</span>
            <span class="token keyword">this</span> <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">-&gt;</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
            exception <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">-&gt;</span> <span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token keyword">else</span> <span class="token operator">-&gt;</span>
                <span class="token keyword">try</span> <span class="token punctuation">{</span>
                    <span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>closeException<span class="token operator">:</span> Throwable<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    <span class="token comment">// cause.addSuppressed(closeException) // ignored here</span>
                <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="闭包"><a href="#闭包" aria-hidden="true" class="header-anchor">#</a> 闭包</h3> <br> <ol><li>函数运行的环境</li> <li>持有函数运行状态</li> <li>函数内部可以定义函数</li> <li>函数内部也可以定义类</li></ol> <br> <h3 id="复合函数"><a href="#复合函数" aria-hidden="true" class="header-anchor">#</a> 复合函数</h3> <p><strong>m(x) = f(g(x))</strong></p> <ul><li>g = g(x) P1:即g函数的参数{x} P2:即g函数的返回值{g}== P2</li> <li>f = f(g) P2:即f函数的参数{g}== P2 R:即f函数的返回值{f}== R</li> <li>m = m(x) P1:即g函数的参数{x}</li></ul> <div class="language-kotlin extra-class"><pre class="language-kotlin"><code>    <span class="token keyword">fun</span> <span class="token function">onTest</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">//m(x) = f(g(x))</span>
        <span class="token keyword">val</span> g <span class="token operator">=</span> <span class="token punctuation">{</span> i<span class="token operator">:</span> Int <span class="token operator">-&gt;</span> i <span class="token operator">+</span> <span class="token number">7</span> <span class="token punctuation">}</span> <span class="token comment">//g(x) = x+7</span>
        <span class="token keyword">val</span> f <span class="token operator">=</span> <span class="token punctuation">{</span> i<span class="token operator">:</span> Int <span class="token operator">-&gt;</span> i <span class="token operator">*</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token comment">//f(g) = g*2</span>
        <span class="token keyword">val</span> m <span class="token operator">=</span> g composite f <span class="token comment">//m(x) = (x+7)*2</span>
        <span class="token keyword">val</span> m1 <span class="token operator">=</span> f composite g <span class="token comment">//m(x) = (x*2)+7</span>
        <span class="token keyword">val</span> value <span class="token operator">=</span> <span class="token function">m</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>
        <span class="token keyword">val</span> value1 <span class="token operator">=</span> <span class="token function">m1</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>
        <span class="token function">println</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
        <span class="token function">println</span><span class="token punctuation">(</span>value1<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>

<span class="token comment">/**
 * @param P1
 * @param P2
 * @param R
 */</span>
<span class="token keyword">infix</span> <span class="token keyword">fun</span> <span class="token operator">&lt;</span>P1<span class="token punctuation">,</span> P2<span class="token punctuation">,</span> R<span class="token operator">&gt;</span> Function1<span class="token operator">&lt;</span>P1<span class="token punctuation">,</span> P2<span class="token operator">&gt;</span><span class="token punctuation">.</span><span class="token function">composite</span><span class="token punctuation">(</span>function<span class="token operator">:</span> Function1<span class="token operator">&lt;</span>P2<span class="token punctuation">,</span> R<span class="token operator">&gt;</span><span class="token punctuation">)</span><span class="token operator">:</span> Function1<span class="token operator">&lt;</span>P1<span class="token punctuation">,</span> R<span class="token operator">&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">fun</span><span class="token punctuation">(</span>p1<span class="token operator">:</span> P1<span class="token punctuation">)</span><span class="token operator">:</span> R <span class="token punctuation">{</span>
        <span class="token keyword">return</span> function<span class="token punctuation">.</span><span class="token function">invoke</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">invoke</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><br> <h3 id="柯里化"><a href="#柯里化" aria-hidden="true" class="header-anchor">#</a> 柯里化</h3> <br>
多元函数变换成一元函数调用链
<div class="language-kotlin extra-class"><pre class="language-kotlin"><code><span class="token keyword">fun</span> <span class="token function">log</span><span class="token punctuation">(</span>tag<span class="token operator">:</span> String<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">fun</span><span class="token punctuation">(</span>target<span class="token operator">:</span> OutputStream<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">fun</span><span class="token punctuation">(</span>message<span class="token operator">:</span> Any<span class="token punctuation">)</span> <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token string">&quot;<span class="token interpolation variable">$tag</span>-<span class="token interpolation variable">$message</span>\n&quot;</span><span class="token punctuation">.</span><span class="token function">toByteArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
 
<span class="token keyword">fun</span> <span class="token function">log1</span><span class="token punctuation">(</span>tag<span class="token operator">:</span>String<span class="token punctuation">,</span>target<span class="token operator">:</span>OutputStream<span class="token punctuation">,</span>message<span class="token operator">:</span> Any<span class="token punctuation">)</span><span class="token punctuation">{</span>
    target<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token string">&quot;<span class="token interpolation variable">$tag</span>-<span class="token interpolation variable">$message</span> \n&quot;</span><span class="token punctuation">.</span><span class="token function">toByteArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
 
<span class="token keyword">fun</span> <span class="token function">main</span><span class="token punctuation">(</span>args<span class="token operator">:</span> Array<span class="token operator">&lt;</span>String<span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;日志&quot;</span><span class="token punctuation">)</span><span class="token punctuation">(</span>System<span class="token punctuation">.</span>out<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token string">&quot;记录日志1&quot;</span><span class="token punctuation">)</span>
    <span class="token operator">::</span>log1<span class="token punctuation">.</span><span class="token function">curried</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token string">&quot;日志&quot;</span><span class="token punctuation">)</span><span class="token punctuation">(</span>System<span class="token punctuation">.</span>out<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token string">&quot;记录日志2&quot;</span><span class="token punctuation">)</span>
 
<span class="token punctuation">}</span>
 
<span class="token keyword">fun</span> <span class="token operator">&lt;</span>P1<span class="token punctuation">,</span> P2<span class="token punctuation">,</span> P3<span class="token punctuation">,</span> R<span class="token operator">&gt;</span> Function3<span class="token operator">&lt;</span>P1<span class="token punctuation">,</span> P2<span class="token punctuation">,</span> P3<span class="token punctuation">,</span> R<span class="token operator">&gt;</span><span class="token punctuation">.</span><span class="token function">curried</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">fun</span><span class="token punctuation">(</span>p1<span class="token operator">:</span> P1<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">fun</span><span class="token punctuation">(</span>p2<span class="token operator">:</span> P2<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">fun</span><span class="token punctuation">(</span>p3<span class="token operator">:</span> P3<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span> p2<span class="token punctuation">,</span> p3<span class="token punctuation">)</span>
</code></pre></div><br> <h3 id="偏函数"><a href="#偏函数" aria-hidden="true" class="header-anchor">#</a> 偏函数</h3> <br>
传入部分参数得到新函数</div></article> <!----></div></div></div> <center><hr width="0%"> <span id="subtitle">&quot;Someday&quot;sounds a lot like the thing people say when they actually mean &quot;Never&quot;. </span> <div class="row"><div class="offset-lg-2 col-lg-8 offset-md-1 col-md-10"><p class="small">© 2019 litton ishir. Code released under the <a href="https://opensource.org/licenses/MIT" target="_blank">MIT License</a></p></div></div></center></div></div>
    <script src="/assets/js/app.b387b3a3.js" defer></script><script src="/assets/js/7.905ce75a.js" defer></script>
  </body>
</html>
